#include <cstdio>
#include "tj_vector.h"
#include "Test.h"

class raw_vectorTest: public TestCase
{
private:
	template <class T>
	class Print
	{
	public:
		void operator()(T x)
		{
			printf("%f ", x);
		}
	};

	template <>
	class Print<int>
	{
	public:
		void operator()(int x)
		{
			printf("%d ", x);
		}
	};

	static void print_string(const char* str) {
		if (str != NULL) printf("%-26s: ", str);
		else printf("%-26s: ", "");
	}

	template <class T>
	static void print (const T& raw, const char* str = NULL) {
		print_string(str);
		for (int i = 0; i < T::Demension; i ++)
		{
			Print<T::Type> print_func;
			print_func(raw.data[i]);
			//print_func(t[i]);
		}
		printf("\n");
	}

	template <>
	static void print<int>(const int& raw, const char* str) 
	{
		print_string(str);

		printf("%d\n", raw);
	}

	template<>
	static void print<float>(const float& raw, const char* str) 
	{
		print_string(str);

		printf("%f\n", raw);
	}

public:
	void proc() {
		raw_vector<float, 3> f3;
		f3.x = 1.0f;
		f3.y = 2.1f;
		f3.z = 3.2f;

		//print(f3, "raw_vector<float, 3>");

		vec4 f40(1.0f, 2.1f, 3.2f);
		print(f40, "f40, without init");

		vec4 f41(1.0f, 2.1f, 3.2f, 0.0f);
		print(f41, "f41, initialized");

		f41.w = 3.0f;
		f41.normalize();
		print(f41, "f41, normalized");

		vec4 f42 = f40 + f41;
		print(f42, "f42 = f40 + f41");

		vec4 f43(f41);
		print(f43, "f43, copy constructor");

		vec4 f44 = 7.0f * f43;
		print(f44, "f44, 7.0 * f43");
		f44 = f43 * 7.0f;
		print(f44, "f44, f43 * 7.0");

		print(f44.length(), "f44.length()");

		vec4 f45(2.0f, 2.0f, 2.0f);
		print(f45, "f45, three param constructor");
		print(f45.length(), "f45.length()");

		print(f45.dot(f44), "f45.dot(f44)");
		print(f45.cross(f44), "f45.cross(f44)");

		vec3 f30(1.0f, 2.0f, 3.0f);
		vec4* pv40 = new vec4(f30);
		print(*pv40, "*pv40, pointer to vec4");
		delete pv40;

		pv40 = new vec4(vec2(3.3f, 2.2f));
		print(*pv40, "*pv40, vec4(vec2(3.3f, 2.2f))");

// 		for (int i = 0; i < 4; i ++) {
// 			printf("%f ", (*pv40)[i]);
// 		}
// 		printf("hello, []\n");
		delete pv40;
		pv40 = NULL;
		
		print((int)sizeof(vec3), "sizeof(vec3)");
		print((int)sizeof(vec2i), "sizeof(vec2i)");
		print((int)sizeof(vec4), "sizeof(vec4)");
// 		vec3 f30(3.0f, 2.0f, 1.0f);
// 		f42 += vec4(f30);
// 		print(f42, "added result");

// 		vec4 array[10];
// 		for (int i = 0; i < 10; i ++) {
// 			print(array[i], "array element");
// 		}

	}
};